package com.such.kit.database.dialect;

import java.util.HashMap;
import java.util.Map;
import com.alibaba.fastjson.JSON;
import com.alibaba.fastjson.TypeReference;
import com.such.kit.database.exception.DatabaseException;
import com.such.kit.placeholder.PlaceholderCommons;
import com.such.kit.resource.support.ReadResource;
import com.such.kit.string.StringCommons;
import com.such.kit.validate.ValidateCommons;

/**
 * @作者 SUCH
 * @日期 2017-9-1 下午4:41:58
 * @描述 数据库数据类型工厂
 * <p>
 * 格式：resourceKey={type: "类型", template: "类型模板"}<br>
 * 可以在函数模板中使用 #[key] 格式占位符<br>
 * </p>
 */
public class TypeFactory {

	/** CHAR [type_char]： */
	public final String CHAR;
	/** NCHAR [type_nchar]： */
	public final String NCHAR;
	/** VARCHAR [type_varchar]： */
	public final String VARCHAR;
	/** NVARCHAR [type_nvarchar]： */
	public final String NVARCHAR;
	/** CLOB [type_clob]： */
	public final String CLOB;
	/** NCLOB [type_nclob]： */
	public final String NCLOB;
	/** INTEGER [type_integer]： */
	public final String INTEGER;
	/** DECIMAL [type_decimal]： */
	public final String DECIMAL;
	/** BLOB [type_blob]： */
	public final String BLOB;
	/** DATE [type_date]： */
	public final String DATE;
	/** DATETIME [type_datetime]： */
	public final String DATETIME;
	/** TIMESTAMP [type_timestamp]： */
	public final String TIMESTAMP;

	private String resourceName;
	private Map<String, String> typeMapping = new HashMap<String, String>();

	public TypeFactory(String resourceName) {
		this.resourceName = resourceName;
		this.CHAR = init("type_char");
		this.NCHAR = init("type_nchar");
		this.VARCHAR = init("type_varchar");
		this.NVARCHAR = init("type_nvarchar");
		this.CLOB = init("type_clob");
		this.NCLOB = init("type_nclob");
		this.INTEGER = init("type_integer");
		this.DECIMAL = init("type_decimal");
		this.BLOB = init("type_blob");
		this.DATE = init("type_date");
		this.DATETIME = init("type_datetime");
		this.TIMESTAMP = init("type_timestamp");
	}

	private String init(String resourceKey) {
		String typeValue = ReadResource.getValue(this.resourceName, resourceKey);
		if (ValidateCommons.isEmpty(typeValue)) {
			throw new DatabaseException(StringCommons.merger("未在 [", this.resourceName, "] 中找到 [", resourceKey, "] 对应的函数模板"));
		}
		Map<String, String> typeObject = JSON.parseObject(typeValue, new TypeReference<Map<String, String>>(){}.getType());
		String type = StringCommons.toUpperCase(typeObject.get("type"));
		String template = typeObject.get("template");
		this.typeMapping.put(type, template);
		return type;
	}

	private String getTemplate(String type) {
		return this.typeMapping.get(StringCommons.toUpperCase(type));
	}

	/**
	 * <p>方法名：typeRenderer</p>
	 * <p>描述：类型渲染器</p>
	 * @param type 数据类型
	 * @param columnSizes 列长度列表，按照参数顺序构建从 #[0] 开始的占位符
	 * @return 类型
	 */
	public String typeRenderer(String type, int... columnSizes) {
		String template = getTemplate(type);
		if (ValidateCommons.isNotEmpty(template)) {
			boolean keepType = true;
			Map<String, String> paramMap = new HashMap<String, String>();
			for (int i = 0;  i < columnSizes.length; i++) {
				int columnSize = columnSizes[i];
				if (columnSize < 0) {
					columnSize = 0;
				}
				if (columnSize > 0) {
					keepType = false;
				}
				paramMap.put(String.valueOf(i), String.valueOf(columnSize));
			}
			if (!keepType) {
				type = PlaceholderCommons.replacePlaceholder(template, paramMap);
			}
		}
		return type;
	}

}
